(function($){


    let parseXml=function(text){
        let xmlDoc;
        try //Internet Explorer
        {
            xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async="false";
            xmlDoc.loadXML(text);
        }
        catch(e)
        {
            try //Firefox, Mozilla, Opera, etc.
            {
                let parser=new DOMParser();
                xmlDoc=parser.parseFromString(text,"text/xml");
            }
            catch(e) {throw new Error("parse xml error:"+e);}
        }
        return xmlDoc;
    }

    let callMap={};
    // let callData={};

    let __Callback_function = function (data) {
        let id = data["callid"];
        //console.log(this);

        //Content-Type
        let data_type=0;//txt,xml,json

        let tmp_ck={};
        for (let i = 0; i <data.header.length; i++) {
            let k=data.header[i];
            switch(k["name"]){
                case "Set-Cookie":
                    let tmp_list=k.elements;
                    for (let j = 0; j < tmp_list.length; j++) {
                        let tmp_data=tmp_list[j];
                        if(j>0&&(tmp_data["value"]==null||tmp_data["value"]===undefined))continue;
                        if(tmp_data["value"]==null||tmp_data["value"]===undefined)tmp_data["value"]="";
                        //tmp_ck[""]
                        tmp_ck[tmp_data["name"]]=tmp_data["value"];
                        // tmp_ck+=tmp_data["name"]+"="+tmp_data["value"]+"; ";
                    }
                    break;
                case "Content-Type":
                    if(k["value"].indexOf("json")>0){
                        data_type=2;
                    }else if(k["value"].indexOf("xml")>0){
                        data_type=1;

                    }
                    break;

            }
        }
        this.cookie(tmp_ck);



        if(id==-1){
            console.log("已丢弃回复");
            return;
        }else {
            let c_data=data["data"];
            try{
                if(data_type==1){
                    try{c_data=parseXml(c_data);}catch (e) {

                    }
                }else if(data_type==2){
                    let s_data=null;
                    try{s_data=JSON.parse(c_data);}catch (e) {

                    }
                    if(s_data==null||typeof s_data!="object"){}else{c_data=s_data;}
                }else{
                    let s_data=null;
                    try{s_data=JSON.parse(c_data);}catch (e) {

                    }
                    if(s_data==null||typeof s_data!="object"){}else{c_data=s_data;}
                }

                callMap[id](c_data,data,this);
            }catch (e) {
                console.error(e);
            }
        }
    }

    $.extend({
        "moon": function () {
            // this.__url="";
            this.__cookie={};
            this.__ua="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36";
            this.__header={
                "Accept-Language": "zh-CN,zh;q=0.9",
                "Cache-Control":" no-cache",
                "Pragma": "no-cache",
                "X-Requested-With":" XMLHttpRequest"
            };
            this.__refer="";
            this.__api="http://127.0.0.1:8001";
            this.__timeout=5000;
            this.__redirect=true;


            let get_headers=function () {
                let o = Object.assign({}, {
                    "User-Agent": this.__ua,
                    "Cookie": this.getRawCookie(),
                    "Refer": this.__refer,
                }, this.__header);
                let out="";
                for (const __key in o) {
                    out+=__key+": "+o[__key]+"\n";
                }
                return out.trim();
            }

            if(new.target === arguments.callee){
                // alert('new调用');
                return Object.assign(this,{
                    "X":function (apiServer) {
                        if(apiServer==null)return this.__api;
                        this.__api=apiServer;
                        return this;
                    },
                    "getRawCookie":function () {
                        let o="";
                        for(let s in this.__cookie){
                            o+=s+"="+this.__cookie[s]+"; ";
                        }
                        return o;
                    }
                    ,
                    "cookie":function (ck) {
                        if(ck==null)return this.__cookie;
                        if(typeof ck=="object"){
                            if(JSON.stringify(ck)==="{}") {
                                this.__cookie = {};
                                return this;
                            }
                            Object.assign(this.__cookie,ck);
                        }
                        let list=ck.split(";");
                        for (let i = 0; i <list.length; i++) {
                            let oo=list[i].trim().split("=");
                            if(oo.length>0)oo[0]=oo[0].trim();

                            if(oo.length>0&&oo[0].length===0)continue;

                            if(oo.length===1){
                                this.__cookie[oo[0]]="";
                            }else if(oo.length===2){
                                this.__cookie[oo[0]]=oo[1].trim();
                            }
                        }

                        // this.__cookie=ck;
                        return this;
                    },
                    "ua":function (ua) {
                        if(ua==null)return this.__ua;
                        this.__ua=ua;
                        return this;
                    },
                    "header":function (header,v) {
                        if(typeof header=="string"&&typeof v=="string"){let tmp_name=header;header={};header[tmp_name]=v;}
                        if(header==null)return this.__header;
                        let o;
                        let olist={};
                        let oo;
                        if (typeof header === "string") {
                            if(header===""){this.__header={};}
                            o = header.split("\n");
                            for (let i = 0; i < o.length; i++) {
                                oo = o[i].split(": ");
                                olist[oo[0]]=oo[1];
                                // olist.push(oo);
                            }
                        }else if(header instanceof Array){
                            for (let i = 0; i < header.length; i++) {
                                oo = o[i].split(": ");
                                olist[oo[0]]=oo[1];
                            }
                        }else if(header instanceof Object){
                            olist=header;
                        }
                        Object.assign(this.__header,olist);
                        return this;
                    },
                    "refer":function (refer) {
                        if(refer==null){return this.__refer;}
                        this.__refer=refer;
                        return this;
                    },
                    "timeout":function (timeout) {
                        if(timeout==null)return this.__timeout;
                        this.__timeout=timeout;
                        return this;
                    },
                    "redirect":function (redirect) {
                        if(redirect==null)return this.__redirect;
                        this.__redirect=redirect;
                    },
                    "get":function (url,callback) {
                        let id;
                        if(typeof callback=="function"){
                            id = new Date().getTime().toString() + Math.ceil(Math.random() * 100000).toString();
                            callMap[id]=callback;
                        }else {
                            id=-1;
                        }
                        let c=this;
                        $.ajax({
                            url:this.__api+"/getApi",
                            data:JSON.stringify({
                                url:url,
                                timeout:this.__timeout,
                                redirect:this.__redirect,
                                head:get_headers.call(this),
                                callid:id
                            }),
                            contentType: "application/json", //必须这样写
                            dataType:"json",
                            type:"POST",
                            success:function(data){__Callback_function.call(c,data)}
                        });
                    },
                    "post":function (url,data,callback) {
                        let id;
                        if(typeof callback=="function"){
                            id = new Date().getTime().toString() + Math.ceil(Math.random() * 100000).toString();
                            callMap[id]=callback;
                        }else {
                            id=-1;
                        }
                        let c=this;
                        $.ajax({
                            url:this.__api+"/postApi",
                            data:JSON.stringify({
                                url:url,
                                timeout:this.__timeout,
                                redirect:this.__redirect,
                                head:get_headers.call(this),

                                callid:id,
                                data:data==null?"": typeof data=="object"? JSON.stringify(data):data
                            }),
                            contentType: "application/json", //必须这样写
                            dataType:"json",
                            type:"POST",
                            success:function(data){__Callback_function.call(c,data)}
                        });
                    }
                });
            }else{
                return new arguments.callee();
                // alert('函数调用');
            }
        },
        "db":function (tbname) {
            this.__db=tbname;
            this.__api="http://127.0.0.1:8001";
            this.__tmp_table={};

            if(new.target === arguments.callee){
                return Object.assign(this,{
                    "read":function (key,defaultvalue) {
                        let data={};
                        let _key=[];
                        if(typeof key=="string"){_key=[key];}else {_key=key;}

                        if(typeof this.__tmp_table[key]=="string")return this.__tmp_table[key];

                        $.ajax({
                            url:this.__api+"/db/read/"+this.__db,
                            async:false,
                            dataType:"json",
                            type:"POST",
                            data:JSON.stringify(_key),
                            success: function(_data){
                                data=_data;
                            }
                        });

                        return  typeof key!="string"?
                            (typeof defaultvalue=="object"?(Object.assign(this.__tmp_table,data),Object.assign({},defaultvalue,data)):data):typeof data[key]=="string"?(this.__tmp_table[key]=data[key]):defaultvalue;
                        // return data;
                    },
                    "write":function (key,value) {
                        if(typeof key=="string"&&value==null)return false;
                        let data={};
                        if(typeof key=="string" && typeof value=="string"){
                            data[key]=value;
                        }else if(typeof key=="object"&&value==null){
                            data=key;
                        }
                        Object.assign(this.__tmp_table,data);
                        $.ajax({
                            url:this.__api+"/db/write/"+this.__db,
                            async:false,
                            dataType:"json",
                            type:"POST",
                            data:JSON.stringify(data),
                            success: function(_data){
                            }
                        });
                        return this;
                    },
                    "unset":function (key) {
                        if(typeof key=="string"){key=[key];}
                        if(!(key instanceof Array))return this;
                        for (let i = 0; i < key.length; i++) {
                            delete this.__tmp_table[key];
                        }
                        $.ajax({
                            url:this.__api+"/db/delete/"+this.__db,
                            async:false,
                            dataType:"json",
                            type:"POST",
                            data:JSON.stringify(key),
                            success: function(_data){
                            }
                        });
                        return this;
                    },
                    "clear":function () {
                        this.__tmp_table={};
                        $.ajax({
                            url:this.__api+"/db/clear/"+this.__db,
                            async:false,
                            dataType:"json",
                            type:"POST",
                            success: function(_data){
                            }
                        });
                        return this;
                    }
                });
            }else{
                return new arguments.callee(tbname);
            }
        }
    });
})(jQuery);